/* \copyright 2023 Zorxx Software. All rights reserved.
 * \license This file is released under the MIT License. See the LICENSE file for details.
 * \brief WS2812 protocol 
 */
#ifndef _WS2812B_PROTOCOL_H
#define _WS2812B_PROTOCOL_H

#include <stdint.h>

/* Each WS2812B pixel requires 24 data bits in the format:
   (G[7 downto 0],R[7 downto 0],B[7 downto 0])
 */

/* It takes 3 serialized bits to send one data bit to a WS2812B */
#define WS2812B_ZERO 0b100
#define WS2812B_ONE  0b110

#define WS2182B_BYTES_PER_COLOR  3
#define WS2182B_COLORS_PER_PIXEL 3
#define WS2182B_BYTES_PER_PIXEL  (WS2182B_BYTES_PER_COLOR * WS2182B_COLORS_PER_PIXEL)

#define WS2812B_BITRATE      2600000UL   /* 2.6 Mbps = 385 ns/bit */
#define WS2812B_RESET_BITS   ((50 * WS2812B_BITRATE / 1000000UL) + 1) /* 50 uS of zero bits sent to end each refresh */
#define WS2812B_RESET_BYTES  ((WS2812B_RESET_BITS + 7) / 8) /* number of zero bytes to send at the end of each refresh */

/* The following is a lookup table to convert a color value (one byte)
   to its corresponding bitstream. A single pixel command is comprised of three
   of these three-byte commands to represent a full green/red/blue value.

   These bits never change: 
   0x00 -> 1001 0010 0100 1001 0010 0100 -> 0x924924

   The following 8 bits (set to 1 below) change based on the desired value
   0100 1001 0010 0100 1001 0010

   This table 768 bytes in size

   See tablegen/tablegen.c
 */
typedef uint8_t ws2812b_pixel[WS2182B_BYTES_PER_COLOR];
const ws2812b_pixel ws2812b_color_map[256] =
{
  { 0x92, 0x49, 0x24 }, /* 0 */
   { 0x92, 0x49, 0x26 }, /* 1 */
   { 0x92, 0x49, 0x34 }, /* 2 */
   { 0x92, 0x49, 0x36 }, /* 3 */
   { 0x92, 0x49, 0xa4 }, /* 4 */
   { 0x92, 0x49, 0xa6 }, /* 5 */
   { 0x92, 0x49, 0xb4 }, /* 6 */
   { 0x92, 0x49, 0xb6 }, /* 7 */
   { 0x92, 0x4d, 0x24 }, /* 8 */
   { 0x92, 0x4d, 0x26 }, /* 9 */
   { 0x92, 0x4d, 0x34 }, /* 10 */
   { 0x92, 0x4d, 0x36 }, /* 11 */
   { 0x92, 0x4d, 0xa4 }, /* 12 */
   { 0x92, 0x4d, 0xa6 }, /* 13 */
   { 0x92, 0x4d, 0xb4 }, /* 14 */
   { 0x92, 0x4d, 0xb6 }, /* 15 */
   { 0x92, 0x69, 0x24 }, /* 16 */
   { 0x92, 0x69, 0x26 }, /* 17 */
   { 0x92, 0x69, 0x34 }, /* 18 */
   { 0x92, 0x69, 0x36 }, /* 19 */
   { 0x92, 0x69, 0xa4 }, /* 20 */
   { 0x92, 0x69, 0xa6 }, /* 21 */
   { 0x92, 0x69, 0xb4 }, /* 22 */
   { 0x92, 0x69, 0xb6 }, /* 23 */
   { 0x92, 0x6d, 0x24 }, /* 24 */
   { 0x92, 0x6d, 0x26 }, /* 25 */
   { 0x92, 0x6d, 0x34 }, /* 26 */
   { 0x92, 0x6d, 0x36 }, /* 27 */
   { 0x92, 0x6d, 0xa4 }, /* 28 */
   { 0x92, 0x6d, 0xa6 }, /* 29 */
   { 0x92, 0x6d, 0xb4 }, /* 30 */
   { 0x92, 0x6d, 0xb6 }, /* 31 */
   { 0x93, 0x49, 0x24 }, /* 32 */
   { 0x93, 0x49, 0x26 }, /* 33 */
   { 0x93, 0x49, 0x34 }, /* 34 */
   { 0x93, 0x49, 0x36 }, /* 35 */
   { 0x93, 0x49, 0xa4 }, /* 36 */
   { 0x93, 0x49, 0xa6 }, /* 37 */
   { 0x93, 0x49, 0xb4 }, /* 38 */
   { 0x93, 0x49, 0xb6 }, /* 39 */
   { 0x93, 0x4d, 0x24 }, /* 40 */
   { 0x93, 0x4d, 0x26 }, /* 41 */
   { 0x93, 0x4d, 0x34 }, /* 42 */
   { 0x93, 0x4d, 0x36 }, /* 43 */
   { 0x93, 0x4d, 0xa4 }, /* 44 */
   { 0x93, 0x4d, 0xa6 }, /* 45 */
   { 0x93, 0x4d, 0xb4 }, /* 46 */
   { 0x93, 0x4d, 0xb6 }, /* 47 */
   { 0x93, 0x69, 0x24 }, /* 48 */
   { 0x93, 0x69, 0x26 }, /* 49 */
   { 0x93, 0x69, 0x34 }, /* 50 */
   { 0x93, 0x69, 0x36 }, /* 51 */
   { 0x93, 0x69, 0xa4 }, /* 52 */
   { 0x93, 0x69, 0xa6 }, /* 53 */
   { 0x93, 0x69, 0xb4 }, /* 54 */
   { 0x93, 0x69, 0xb6 }, /* 55 */
   { 0x93, 0x6d, 0x24 }, /* 56 */
   { 0x93, 0x6d, 0x26 }, /* 57 */
   { 0x93, 0x6d, 0x34 }, /* 58 */
   { 0x93, 0x6d, 0x36 }, /* 59 */
   { 0x93, 0x6d, 0xa4 }, /* 60 */
   { 0x93, 0x6d, 0xa6 }, /* 61 */
   { 0x93, 0x6d, 0xb4 }, /* 62 */
   { 0x93, 0x6d, 0xb6 }, /* 63 */
   { 0x9a, 0x49, 0x24 }, /* 64 */
   { 0x9a, 0x49, 0x26 }, /* 65 */
   { 0x9a, 0x49, 0x34 }, /* 66 */
   { 0x9a, 0x49, 0x36 }, /* 67 */
   { 0x9a, 0x49, 0xa4 }, /* 68 */
   { 0x9a, 0x49, 0xa6 }, /* 69 */
   { 0x9a, 0x49, 0xb4 }, /* 70 */
   { 0x9a, 0x49, 0xb6 }, /* 71 */
   { 0x9a, 0x4d, 0x24 }, /* 72 */
   { 0x9a, 0x4d, 0x26 }, /* 73 */
   { 0x9a, 0x4d, 0x34 }, /* 74 */
   { 0x9a, 0x4d, 0x36 }, /* 75 */
   { 0x9a, 0x4d, 0xa4 }, /* 76 */
   { 0x9a, 0x4d, 0xa6 }, /* 77 */
   { 0x9a, 0x4d, 0xb4 }, /* 78 */
   { 0x9a, 0x4d, 0xb6 }, /* 79 */
   { 0x9a, 0x69, 0x24 }, /* 80 */
   { 0x9a, 0x69, 0x26 }, /* 81 */
   { 0x9a, 0x69, 0x34 }, /* 82 */
   { 0x9a, 0x69, 0x36 }, /* 83 */
   { 0x9a, 0x69, 0xa4 }, /* 84 */
   { 0x9a, 0x69, 0xa6 }, /* 85 */
   { 0x9a, 0x69, 0xb4 }, /* 86 */
   { 0x9a, 0x69, 0xb6 }, /* 87 */
   { 0x9a, 0x6d, 0x24 }, /* 88 */
   { 0x9a, 0x6d, 0x26 }, /* 89 */
   { 0x9a, 0x6d, 0x34 }, /* 90 */
   { 0x9a, 0x6d, 0x36 }, /* 91 */
   { 0x9a, 0x6d, 0xa4 }, /* 92 */
   { 0x9a, 0x6d, 0xa6 }, /* 93 */
   { 0x9a, 0x6d, 0xb4 }, /* 94 */
   { 0x9a, 0x6d, 0xb6 }, /* 95 */
   { 0x9b, 0x49, 0x24 }, /* 96 */
   { 0x9b, 0x49, 0x26 }, /* 97 */
   { 0x9b, 0x49, 0x34 }, /* 98 */
   { 0x9b, 0x49, 0x36 }, /* 99 */
   { 0x9b, 0x49, 0xa4 }, /* 100 */
   { 0x9b, 0x49, 0xa6 }, /* 101 */
   { 0x9b, 0x49, 0xb4 }, /* 102 */
   { 0x9b, 0x49, 0xb6 }, /* 103 */
   { 0x9b, 0x4d, 0x24 }, /* 104 */
   { 0x9b, 0x4d, 0x26 }, /* 105 */
   { 0x9b, 0x4d, 0x34 }, /* 106 */
   { 0x9b, 0x4d, 0x36 }, /* 107 */
   { 0x9b, 0x4d, 0xa4 }, /* 108 */
   { 0x9b, 0x4d, 0xa6 }, /* 109 */
   { 0x9b, 0x4d, 0xb4 }, /* 110 */
   { 0x9b, 0x4d, 0xb6 }, /* 111 */
   { 0x9b, 0x69, 0x24 }, /* 112 */
   { 0x9b, 0x69, 0x26 }, /* 113 */
   { 0x9b, 0x69, 0x34 }, /* 114 */
   { 0x9b, 0x69, 0x36 }, /* 115 */
   { 0x9b, 0x69, 0xa4 }, /* 116 */
   { 0x9b, 0x69, 0xa6 }, /* 117 */
   { 0x9b, 0x69, 0xb4 }, /* 118 */
   { 0x9b, 0x69, 0xb6 }, /* 119 */
   { 0x9b, 0x6d, 0x24 }, /* 120 */
   { 0x9b, 0x6d, 0x26 }, /* 121 */
   { 0x9b, 0x6d, 0x34 }, /* 122 */
   { 0x9b, 0x6d, 0x36 }, /* 123 */
   { 0x9b, 0x6d, 0xa4 }, /* 124 */
   { 0x9b, 0x6d, 0xa6 }, /* 125 */
   { 0x9b, 0x6d, 0xb4 }, /* 126 */
   { 0x9b, 0x6d, 0xb6 }, /* 127 */
   { 0xd2, 0x49, 0x24 }, /* 128 */
   { 0xd2, 0x49, 0x26 }, /* 129 */
   { 0xd2, 0x49, 0x34 }, /* 130 */
   { 0xd2, 0x49, 0x36 }, /* 131 */
   { 0xd2, 0x49, 0xa4 }, /* 132 */
   { 0xd2, 0x49, 0xa6 }, /* 133 */
   { 0xd2, 0x49, 0xb4 }, /* 134 */
   { 0xd2, 0x49, 0xb6 }, /* 135 */
   { 0xd2, 0x4d, 0x24 }, /* 136 */
   { 0xd2, 0x4d, 0x26 }, /* 137 */
   { 0xd2, 0x4d, 0x34 }, /* 138 */
   { 0xd2, 0x4d, 0x36 }, /* 139 */
   { 0xd2, 0x4d, 0xa4 }, /* 140 */
   { 0xd2, 0x4d, 0xa6 }, /* 141 */
   { 0xd2, 0x4d, 0xb4 }, /* 142 */
   { 0xd2, 0x4d, 0xb6 }, /* 143 */
   { 0xd2, 0x69, 0x24 }, /* 144 */
   { 0xd2, 0x69, 0x26 }, /* 145 */
   { 0xd2, 0x69, 0x34 }, /* 146 */
   { 0xd2, 0x69, 0x36 }, /* 147 */
   { 0xd2, 0x69, 0xa4 }, /* 148 */
   { 0xd2, 0x69, 0xa6 }, /* 149 */
   { 0xd2, 0x69, 0xb4 }, /* 150 */
   { 0xd2, 0x69, 0xb6 }, /* 151 */
   { 0xd2, 0x6d, 0x24 }, /* 152 */
   { 0xd2, 0x6d, 0x26 }, /* 153 */
   { 0xd2, 0x6d, 0x34 }, /* 154 */
   { 0xd2, 0x6d, 0x36 }, /* 155 */
   { 0xd2, 0x6d, 0xa4 }, /* 156 */
   { 0xd2, 0x6d, 0xa6 }, /* 157 */
   { 0xd2, 0x6d, 0xb4 }, /* 158 */
   { 0xd2, 0x6d, 0xb6 }, /* 159 */
   { 0xd3, 0x49, 0x24 }, /* 160 */
   { 0xd3, 0x49, 0x26 }, /* 161 */
   { 0xd3, 0x49, 0x34 }, /* 162 */
   { 0xd3, 0x49, 0x36 }, /* 163 */
   { 0xd3, 0x49, 0xa4 }, /* 164 */
   { 0xd3, 0x49, 0xa6 }, /* 165 */
   { 0xd3, 0x49, 0xb4 }, /* 166 */
   { 0xd3, 0x49, 0xb6 }, /* 167 */
   { 0xd3, 0x4d, 0x24 }, /* 168 */
   { 0xd3, 0x4d, 0x26 }, /* 169 */
   { 0xd3, 0x4d, 0x34 }, /* 170 */
   { 0xd3, 0x4d, 0x36 }, /* 171 */
   { 0xd3, 0x4d, 0xa4 }, /* 172 */
   { 0xd3, 0x4d, 0xa6 }, /* 173 */
   { 0xd3, 0x4d, 0xb4 }, /* 174 */
   { 0xd3, 0x4d, 0xb6 }, /* 175 */
   { 0xd3, 0x69, 0x24 }, /* 176 */
   { 0xd3, 0x69, 0x26 }, /* 177 */
   { 0xd3, 0x69, 0x34 }, /* 178 */
   { 0xd3, 0x69, 0x36 }, /* 179 */
   { 0xd3, 0x69, 0xa4 }, /* 180 */
   { 0xd3, 0x69, 0xa6 }, /* 181 */
   { 0xd3, 0x69, 0xb4 }, /* 182 */
   { 0xd3, 0x69, 0xb6 }, /* 183 */
   { 0xd3, 0x6d, 0x24 }, /* 184 */
   { 0xd3, 0x6d, 0x26 }, /* 185 */
   { 0xd3, 0x6d, 0x34 }, /* 186 */
   { 0xd3, 0x6d, 0x36 }, /* 187 */
   { 0xd3, 0x6d, 0xa4 }, /* 188 */
   { 0xd3, 0x6d, 0xa6 }, /* 189 */
   { 0xd3, 0x6d, 0xb4 }, /* 190 */
   { 0xd3, 0x6d, 0xb6 }, /* 191 */
   { 0xda, 0x49, 0x24 }, /* 192 */
   { 0xda, 0x49, 0x26 }, /* 193 */
   { 0xda, 0x49, 0x34 }, /* 194 */
   { 0xda, 0x49, 0x36 }, /* 195 */
   { 0xda, 0x49, 0xa4 }, /* 196 */
   { 0xda, 0x49, 0xa6 }, /* 197 */
   { 0xda, 0x49, 0xb4 }, /* 198 */
   { 0xda, 0x49, 0xb6 }, /* 199 */
   { 0xda, 0x4d, 0x24 }, /* 200 */
   { 0xda, 0x4d, 0x26 }, /* 201 */
   { 0xda, 0x4d, 0x34 }, /* 202 */
   { 0xda, 0x4d, 0x36 }, /* 203 */
   { 0xda, 0x4d, 0xa4 }, /* 204 */
   { 0xda, 0x4d, 0xa6 }, /* 205 */
   { 0xda, 0x4d, 0xb4 }, /* 206 */
   { 0xda, 0x4d, 0xb6 }, /* 207 */
   { 0xda, 0x69, 0x24 }, /* 208 */
   { 0xda, 0x69, 0x26 }, /* 209 */
   { 0xda, 0x69, 0x34 }, /* 210 */
   { 0xda, 0x69, 0x36 }, /* 211 */
   { 0xda, 0x69, 0xa4 }, /* 212 */
   { 0xda, 0x69, 0xa6 }, /* 213 */
   { 0xda, 0x69, 0xb4 }, /* 214 */
   { 0xda, 0x69, 0xb6 }, /* 215 */
   { 0xda, 0x6d, 0x24 }, /* 216 */
   { 0xda, 0x6d, 0x26 }, /* 217 */
   { 0xda, 0x6d, 0x34 }, /* 218 */
   { 0xda, 0x6d, 0x36 }, /* 219 */
   { 0xda, 0x6d, 0xa4 }, /* 220 */
   { 0xda, 0x6d, 0xa6 }, /* 221 */
   { 0xda, 0x6d, 0xb4 }, /* 222 */
   { 0xda, 0x6d, 0xb6 }, /* 223 */
   { 0xdb, 0x49, 0x24 }, /* 224 */
   { 0xdb, 0x49, 0x26 }, /* 225 */
   { 0xdb, 0x49, 0x34 }, /* 226 */
   { 0xdb, 0x49, 0x36 }, /* 227 */
   { 0xdb, 0x49, 0xa4 }, /* 228 */
   { 0xdb, 0x49, 0xa6 }, /* 229 */
   { 0xdb, 0x49, 0xb4 }, /* 230 */
   { 0xdb, 0x49, 0xb6 }, /* 231 */
   { 0xdb, 0x4d, 0x24 }, /* 232 */
   { 0xdb, 0x4d, 0x26 }, /* 233 */
   { 0xdb, 0x4d, 0x34 }, /* 234 */
   { 0xdb, 0x4d, 0x36 }, /* 235 */
   { 0xdb, 0x4d, 0xa4 }, /* 236 */
   { 0xdb, 0x4d, 0xa6 }, /* 237 */
   { 0xdb, 0x4d, 0xb4 }, /* 238 */
   { 0xdb, 0x4d, 0xb6 }, /* 239 */
   { 0xdb, 0x69, 0x24 }, /* 240 */
   { 0xdb, 0x69, 0x26 }, /* 241 */
   { 0xdb, 0x69, 0x34 }, /* 242 */
   { 0xdb, 0x69, 0x36 }, /* 243 */
   { 0xdb, 0x69, 0xa4 }, /* 244 */
   { 0xdb, 0x69, 0xa6 }, /* 245 */
   { 0xdb, 0x69, 0xb4 }, /* 246 */
   { 0xdb, 0x69, 0xb6 }, /* 247 */
   { 0xdb, 0x6d, 0x24 }, /* 248 */
   { 0xdb, 0x6d, 0x26 }, /* 249 */
   { 0xdb, 0x6d, 0x34 }, /* 250 */
   { 0xdb, 0x6d, 0x36 }, /* 251 */
   { 0xdb, 0x6d, 0xa4 }, /* 252 */
   { 0xdb, 0x6d, 0xa6 }, /* 253 */
   { 0xdb, 0x6d, 0xb4 }, /* 254 */
   { 0xdb, 0x6d, 0xb6 }, /* 255 */
};

#endif /* _WS2812B_PROTOCOL_H */